﻿using GalaSoft.MvvmLight;
using MyImdb.Common;
using MyImdb.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyImdb.ViewModel
{
    internal class AllItemsViewModel : ViewModelBase
    {
        /// <summary>
        /// The _ imdb titles
        /// </summary>
        private ObservableCollection<ImdbItem> _ImdbTitles;
        /// <summary>
        /// Gets or sets the imdb titles.
        /// </summary>
        /// <value>
        /// The imdb titles.
        /// </value>
        public ObservableCollection<ImdbItem> ImdbTitles
        {
            get { return _ImdbTitles; }
            set
            {
                _ImdbTitles = value;
                RaisePropertyChanged("ImdbTitles");
            }
        }

        private ObservableCollection<ImdbItem> _FilteredItems;
        public ObservableCollection<ImdbItem> FilteredItems
        {
            get { return _FilteredItems; }
            set
            {
                _FilteredItems = value;
                if (_FilteredItems == null)
                {
                    ItemsCount = 0;
                }
                else
                {
                    ItemsCount = _FilteredItems.Count;
                }
                RaisePropertyChanged("FilteredItems");
            }
        }

        private bool _IsMovies;
        public bool IsMovies
        {
            get { return _IsMovies; }
            set
            {
                _IsMovies = value;
                if (_IsMovies)
                {
                    FilteredItems = ImdbTitles.Where(t => t.Episodes == null).ToObservableCollection();
                }
                RaisePropertyChanged("IsMovies");
            }
        }

        private bool _IsTvSeries;
        public bool IsTvSeries
        {
            get { return _IsTvSeries; }
            set
            {
                _IsTvSeries = value;
                if (_IsTvSeries)
                {
                    FilteredItems = ImdbTitles.Where(t => t.Episodes != null).ToObservableCollection();
                }
                RaisePropertyChanged("IsTvSeries");
            }
        }

        private bool _IsYear;
        public bool IsYear
        {
            get { return _IsYear; }
            set
            {
                _IsYear = value;
                if (!_IsYear)
                {
                    SelectedYear = null;
                }
                RaisePropertyChanged("IsYear");
            }
        }

        private bool _IsAll;
        public bool IsAll
        {
            get { return _IsAll; }
            set
            {
                _IsAll = value;
                if (_IsAll)
                {
                    FilteredItems = ImdbTitles.Where(t => t is ImdbItem).ToObservableCollection();
                }
                RaisePropertyChanged("IsAll");
            }
        }

        private bool _IsStartsWith;
        public bool IsStartsWith
        {
            get { return _IsStartsWith; }
            set
            {
                _IsStartsWith = value;
                if (!_IsStartsWith)
                {
                    SelectedStartsWith = null;
                }
                RaisePropertyChanged("IsStartsWith");
            }
        }

        private bool _IsActor;
        public bool IsActor
        {
            get { return _IsActor; }
            set
            {
                _IsActor = value;
                if (!_IsActor)
                {
                    SelectedActor = null;
                }
                RaisePropertyChanged("IsActor");
            }
        }

        private ObservableCollection<int> _Years;
        public ObservableCollection<int> Years
        {
            get { return _Years; }
            set
            {
                _Years = value;
                RaisePropertyChanged("Years");
            }
        }

        private int? _SelectedYear;
        public int? SelectedYear
        {
            get { return _SelectedYear; }
            set
            {
                _SelectedYear = value;
                if (_SelectedYear != null)
                {
                    if (_SelectedYear != -1)
                    {
                        FilteredItems = ImdbTitles.Where(t => t.Year == _SelectedYear).ToObservableCollection();
                    } 
                }
                RaisePropertyChanged("SelectedYear");
            }
        }

        private ObservableCollection<string> _StartsWiths;
        public ObservableCollection<string> StartsWiths
        {
            get { return _StartsWiths; }
            set
            {
                _StartsWiths = value;
                RaisePropertyChanged("StartsWiths");
            }
        }

        private string _SelectedStartsWith;
        public string SelectedStartsWith
        {
            get { return _SelectedStartsWith; }
            set
            {
                _SelectedStartsWith = value;
                if (!string.IsNullOrEmpty(_SelectedStartsWith))
                {
                    if (!_SelectedStartsWith.Equals("0~9"))
                    {
                        FilteredItems = ImdbTitles.Where(t => t.Title.StartsWith(_SelectedStartsWith)).ToObservableCollection();
                    }
                    else
                    {
                        FilteredItems = new ObservableCollection<ImdbItem>();
                        foreach (var title in ImdbTitles)
                        {
                            var startsWith = title.Title.Substring(0, 1);
                            switch (startsWith)
                            {
                                case "0":
                                case "1":
                                case "2":
                                case "3":
                                case "4":
                                case "5":
                                case "6":
                                case "7":
                                case "8":
                                case "9":
                                    FilteredItems.Add(title);
                                    break;
                            }
                        }
                    }
                }
                RaisePropertyChanged("SelectedStartsWith");
            }
        }

        private ObservableCollection<string> _Actors;
        public ObservableCollection<string> Actors
        {
            get { return _Actors; }
            set
            {
                _Actors = value;
                RaisePropertyChanged("Actors");
            }
        }

        private string _SelectedActor;
        public string SelectedActor
        {
            get { return _SelectedActor; }
            set
            {
                _SelectedActor = value;
                if (!string.IsNullOrEmpty(_SelectedActor))
                {
                    FilteredItems = ImdbTitles.Where(t => t.Actors.Contains(_SelectedActor)).ToObservableCollection();
                }
                RaisePropertyChanged("SelectedActor");
            }
        }

        private int _ItemsCount;
        public int ItemsCount
        {
            get { return _ItemsCount; }
            set
            {
                _ItemsCount = value;
                RaisePropertyChanged("ItemsCount");
            }
        }

        private Settings _AppSettings;
        public Settings AppSettings
        {
            get { return _AppSettings; }
            set
            {
                _AppSettings = value;
                RaisePropertyChanged("AppSettings");
            }
        }

        public AllItemsViewModel()
        {
            ReadSettings();
            ImdbTitles = new ObservableCollection<ImdbItem>();
            StartsWiths = new ObservableCollection<string> 
            {
                "0~9","A","B","C", "D","E", "F", "G", "H", "I", "J", "K", "L",
                "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
            };

            if (FileHelper.IsDatabaseExist(AppSettings.DatabasePath))
            {
                FileHelper.DatabaseBasePath = AppSettings.DatabasePath;

                var titleList = FileHelper.ReadTitles();
                if (titleList != null)
                {
                    Years = new ObservableCollection<int>();
                    Actors = new ObservableCollection<string>();

                    foreach (var title in titleList)
                    {
                        var imdbTitle = FileHelper.ReadTitle(title);
                        if (imdbTitle != null)
                        {
                            ImdbTitles.Add(imdbTitle);
                            if (!Years.Contains(imdbTitle.Year))
                            {
                                Years.Add(imdbTitle.Year);
                            }

                            foreach (var actor in imdbTitle.Actors)
                            {
                                if (!Actors.Contains(actor))
                                {
                                    Actors.Add(actor);
                                }
                            }
                        }
                    }
                    ImdbTitles = ImdbTitles.OrderBy(t => t.Title).ToObservableCollection();
                    Years = Years.OrderByDescending(t => t).ToObservableCollection();
                    Actors = Actors.OrderBy(t => t).ToObservableCollection();
                } 
            }
            else
            {
                //No Database path
            }
        }

        private void ReadSettings()
        {
            AppSettings = FileHelper.ReadSettings();
            FileHelper.DatabaseBasePath = AppSettings.DatabasePath;
        }
    }
}
